package storage

import (
	"io"
	"os"
	"path/filepath"

	"jdfs2/internal/utils"
)

type FS struct {
	root string
}

func NewFS(root string) *FS {
	return &FS{root: root}
}

func (fs *FS) PutObject(bucket, key string, r io.Reader, size int64) error {
	dstPath := filepath.Join(fs.root, bucket, key)
	if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil {
		return err
	}
	f, err := os.Create(dstPath)
	if err != nil {
		return err
	}
	defer f.Close()
	_, err = io.CopyN(f, r, size)
	return err
}

// GetObject opens a file for reading.
// It returns an *os.File handle that the caller is responsible for closing.
func (fs *FS) GetObject(bucket, key string) (*os.File, error) {
	path := filepath.Join(fs.root, bucket, key)
	file, err := os.Open(path)
	if err != nil {
		if os.IsNotExist(err) {
			// Return a standard S3 error for this case.
			return nil, utils.ErrNoSuchKey
		}
		return nil, err
	}
	return file, nil
}

// DeleteObject removes a file from the filesystem.
func (fs *FS) DeleteObject(bucket, key string) error {
	path := filepath.Join(fs.root, bucket, key)
	err := os.Remove(path)
	if err != nil && !os.IsNotExist(err) {
		return err
	}
	// S3's DeleteObject is idempotent. If the object doesn't exist,
	// it's considered a success. So we ignore os.IsNotExist errors.
	return nil
}

// TODO: 添加 GetObject, DeleteObject 等方法
